﻿package kliment.display.draw {
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	import kliment.display.draw.shape.ArcShape;
	import kliment.display.draw.shape.BurstShape;
	import kliment.display.draw.shape.CircleShape;
	import kliment.display.draw.shape.ColorBarShape;
	import kliment.display.draw.shape.ColorWheelBitmap;
	import kliment.display.draw.shape.ColorWheelShape;
	import kliment.display.draw.shape.EllipseShape;
	import kliment.display.draw.shape.LinesShape;
	import kliment.display.draw.shape.PolyShape;
	import kliment.display.draw.shape.RectangleShape;
	import kliment.display.draw.shape.RoundRectangleShape;
	import kliment.display.draw.shape.SpiralShape;
	import kliment.display.draw.shape.StarShape;
	import kliment.display.draw.shape.TrapeziumBy2PointsShape;
	import kliment.display.draw.shape.TriangleByCornerShape;
	import kliment.display.draw.shape.TriangleByEdgeShape;
	import kliment.display.draw.style.LineStyle;
	import kliment.geom.PointExtended;

	/**
	* ...
	* @author Kliment
	*/
	public class Draw {

		static public function line(fromPoint:Point, toPoint:Point, drawStyle:DrawStyle = null, cell:* = null):DisplayObject {
			if (cell != null) {
				fromPoint = fromPoint.clone();
				fromPoint = fromPoint.clone();
				cell.x = fromPoint.x;
				cell.y = fromPoint.y;
				toPoint.x -= fromPoint.x,
				toPoint.y -= fromPoint.y;
				fromPoint.x = fromPoint.y = 0;
			}
			var line:Shape = new Shape();
			if (!drawStyle)
				drawStyle = new DrawStyle(null, new LineStyle(1));
			if (!drawStyle.lineStyle)
				drawStyle.lineStyle = new LineStyle(1);

			if (drawStyle.lineStyle)
				line.graphics.lineStyle(drawStyle.lineStyle.width, drawStyle.lineStyle.color, drawStyle.lineStyle.alpha, drawStyle.lineStyle.pixelHinting, drawStyle.lineStyle.scaleMode, drawStyle.lineStyle.caps, drawStyle.lineStyle.joints, drawStyle.lineStyle.miterLimit);
			if (drawStyle.lineGradientStyle)
				line.graphics.lineGradientStyle(drawStyle.lineGradientStyle.type, drawStyle.lineGradientStyle.colors, drawStyle.lineGradientStyle.alphas, drawStyle.lineGradientStyle.ratios, drawStyle.lineGradientStyle.matrix, drawStyle.lineGradientStyle.spreadMethod, drawStyle.lineGradientStyle.interpolationMethod, drawStyle.lineGradientStyle.focalPointRatio)

			line.graphics.moveTo(fromPoint.x, fromPoint.y);
			line.graphics.lineTo(toPoint.x, toPoint.y);
			line.graphics.endFill();
			return returnObject(line, cell);
		}

		static public function lines(position:Point, points:Array, drawStyle:DrawStyle = null, cell:* = null):DisplayObject {
			if (cell != null) {
				position = position.clone();
				cell.x = position.x;
				cell.y = position.y;
				position.x = position.y = 0;
			}
			var lines:Shape = new LinesShape(position, points, drawStyle);
			return returnObject(lines, cell);
		}

		static public function rectangle(size:Rectangle, drawStyle:DrawStyle = null, cell:* = null):DisplayObject {
			if (cell != null) {
				size = size.clone();
				cell.x = size.x;
				cell.y = size.y;
				size.x = size.y = 0;
			}
			var rectangle:Shape = new RectangleShape(size, drawStyle);
			return returnObject(rectangle, cell);
		}

		static public function roundedRectangle(size:Rectangle, cornerRadius:Number = 3, drawStyle:DrawStyle = null, cell:* = null):DisplayObject {
			if (cell != null){
				size = size.clone();
				cell.x = size.x;
				cell.y = size.y;
				size.x = size.y = 0;
			}
			var roundedRectangle:Shape = new RoundRectangleShape(size, cornerRadius, drawStyle);
			return returnObject(roundedRectangle, cell);
		}

		static public function triangleByCorner(a:Point, b:Point, c:Point, drawStyle:DrawStyle = null, cell:* = null):DisplayObject {
			if (cell != null) {
				a = a.clone();
				b = b.clone();
				c = c.clone();
				cell.x = (a.x + b.x + c.x) / 3; cell.y = (a.y + b.y + c.y) / 3;
				a.x -= cell.x; a.y -= cell.y;
				b.x -= cell.x; b.y -= cell.y;
				c.x -= cell.x; c.y -= cell.y
			}
			var triangle:Shape = new TriangleByCornerShape(a, b, c, drawStyle);
			return returnObject(triangle, cell);
		}

		static public function triangleByEdge(position:Point, a:Number, b:Number, c:Number, drawStyle:DrawStyle = null, cell:* = null):DisplayObject {
			if (cell != null){
				position = position.clone();
				cell.x = position.x;
				cell.y = position.y;
				position.x = position.y = 0;
			}
			var triangle:Shape = new TriangleByEdgeShape(a, b, c, drawStyle);
			return returnObject(triangle, cell);
		}

		static public function circle(center:Point, radius:Number = 100, drawStyle:DrawStyle = null, cell:* = null):DisplayObject {
			if (cell != null){
				center = center.clone();
				cell.x = center.x;
				cell.y = center.y;
				center.x = center.y = 0;
			}
			var circle:Shape = new CircleShape(center, radius, drawStyle);
			return returnObject(circle, cell);
		}

		static public function ellipse(center:Point, width:Number, height:Number, drawStyle:DrawStyle = null, cell:* = null):DisplayObject {
			if (cell != null){
				center = center.clone();
				cell.x = center.x;
				cell.y = center.y;
				center.x = center.y = 0;
			}
			var ellipse:Shape = new EllipseShape(center, width, height, drawStyle)
			return returnObject(ellipse, cell);
		}

		static public function star(center:Point, points:Number = 5, innerRadius:Number = 30, outerRadius:Number = 40, angle:Number = 0, drawStyle:DrawStyle = null, cell:* = null):DisplayObject {
			if (cell != null){
				center = center.clone();
				cell.x = center.x;
				cell.y = center.y;
				center.x = center.y = 0;
			}
			var star:Shape = new StarShape(center, points, innerRadius, outerRadius, angle, drawStyle);
			return returnObject(star, cell);
		}

		static public function poly(center:Point, sides:int = 5, radius:Number = 100, angle:Number = 0, drawStyle:DrawStyle = null, cell:* = null):DisplayObject {
			if (cell != null){
				center = center.clone();
				cell.x = center.x;
				cell.y = center.y;
				center.x = center.y = 0;
			}
			var poly:Shape = new PolyShape(center, sides, radius, angle, drawStyle)
			return returnObject(poly, cell);
		}

		static public function burst(center:Point, sides:int = 5, innerRadius:Number = 30, outerRadius:Number = 40, angle:Number = 0, drawStyle:DrawStyle = null, cell:* = null):DisplayObject {
			if (cell != null){
				center = center.clone();
				cell.x = center.x;
				cell.y = center.y;
				center.x = center.y = 0;
			}
			var burst:Shape = new BurstShape(center, sides, innerRadius, outerRadius, angle, drawStyle)
			return returnObject(burst, cell);
		}

		static public function arc(center:Point, radius:Number = 100, start:Number = 0, end:Number = 360, type:String = 'chord', yRadius:Number = 0, drawStyle:DrawStyle = null, cell:* = null):DisplayObject {
			if (cell != null){
				center = center.clone();
				cell.x = center.x;
				cell.y = center.y;
				center.x = center.y = 0;
			}
			var arc:Shape = new ArcShape(center, radius, start, end, type, yRadius, drawStyle)
			return returnObject(arc, cell);
		}

		static public function spiral(center:Point, xRadius:Number = 0, yRadius:Number = 0, xGrowth:Number = 9, yGrowth:Number = 9, startAngle:Number = 0, revolutions:Number = 9, drawStyle:DrawStyle = null, cell:* = null):DisplayObject {
			if (cell != null){
				center = center.clone();
				cell.x = center.x;
				cell.y = center.y;
				center.x = center.y = 0;
			}
			var spiral:Shape = new SpiralShape(center, xRadius, yRadius, xGrowth, yGrowth, startAngle, revolutions, drawStyle);
			return returnObject(spiral, cell);
		}

		static public function trapeziumBy2Points(a:PointExtended, b:PointExtended, width:Number, drawStyle:DrawStyle = null, cell:* = null):DisplayObject {
			var shape:Shape = new TrapeziumBy2PointsShape(a, b, width, drawStyle);
			return returnObject(shape, cell);
		}

		static public function colorBar(size:Rectangle, cell:* = null):DisplayObject {
			var shape:Shape = new ColorBarShape(size);
			return returnObject(shape, cell);
		}

		static public function colorWheel(center:Point, radius:Number, cell:* = null):DisplayObject {
			var shape:Shape = new ColorWheelShape(center, radius);
			return returnObject(shape, cell);
		}

		static public function colorWheelBitmap(center:Point, radius:Number, cell:* = null):ColorWheelBitmap {
			var shape:ColorWheelBitmap = new ColorWheelBitmap(center, radius);
			return shape;
		}

		private static function returnObject(src:Shape , cell:* = null):DisplayObject {
			if (cell != null) {
				cell.addChild(src);
				return cell;
			}
			return src;
		}
	}
}